exports = module.exports = function(io, client, subscriber, publisher) {
  io.on('connection', function(socket){
    /**
     * 用户登录，记录当前用户信息
     */
    socket.on('user login', function(info){
      // 储存用户状态,redis对象,key user-[userId]: 0|1
      socket.statusKey = 'user-' + info.userId;
      // redis订阅用户通知,频道名:notification-[userId]
      socket.channel = 'notification-' + info.userId;
      // 当前用户ID
      socket.userId = info.userId;
      client.set(socket.statusKey, 1);
      subscriber.subscribe(socket.channel);
    });

    /**
     * 发送私信
     * 用户加入房间
     * 更新当前房间列表
     */
    socket.on('join chatroom', function(chatroom){
      // 用户当前的聊天室ID
      socket.currentChatroom = chatroom;

      client.get(chatroom, function(err, reply) {
        if (!reply || reply == null) {
          var arr = [];
          arr.push(parseInt(socket.userId));
          client.set(chatroom, JSON.stringify(arr));
        } else {
          var arr = JSON.parse(reply);
          if (!contains(arr, parseInt(socket.userId))) {
            arr.push(parseInt(socket.userId));
            client.set(chatroom, JSON.stringify(arr));
          }
        }
      });

      socket.join(chatroom);
    });

    /**
     * 用户离开聊天室
     */
    socket.on('leave chatroom', function (chatroom) {
      // 移除当前聊天室ID
      socket.currentChatroom = null;

      client.get(chatroom, function(err, reply) {
        var arr = JSON.parse(reply);
        if (contains(arr, parseInt(socket.userId))) {
          removeByValue(arr, parseInt(socket.userId));
          client.set(chatroom, JSON.stringify(arr));
        }
      });

      socket.leave(chatroom);
    });

    /**
     * 收发私信
     * 如果对方用户不在房间内则发送通知
     */
    socket.on('chat', function(chatroom, message){
      // 对方用户的redis订阅事件名
      var thisChannel = 'notification-' + message.companion_id;

      client.get(chatroom, function(err, reply) {
        var arr = JSON.parse(reply);
        if (contains(arr, parseInt(message.companion_id))) {
          socket.broadcast.to(chatroom).emit('new message', message);
        } else {
          // 信息转码为JSON字符串
          publisher.publish(thisChannel, JSON.stringify(message));
        }
      });
    });

    /**
     * 用户退出
     */
    socket.on('disconnect', function () {
      // 如果存在开启的聊天室则删除房间内用户信息
      if (socket.currentChatroom) {
        client.get(socket.currentChatroom, function(err, reply) {
          var arr = JSON.parse(reply);
          if (contains(arr, parseInt(socket.userId))) {
            removeByValue(arr, parseInt(socket.userId));
            client.set(socket.currentChatroom, JSON.stringify(arr));

            socket.currentChatroom = null;
            socket.leave(socket.currentChatroom);
          }
        });
      }

      // 不在线
      if (socket.statusKey) {
        client.set(socket.statusKey, 0);
      }

      subscriber.unsubscribe(socket.channel);
    });
  });
};

/**
 * 判断数组元素是否存在
 */
function contains(arr, obj) {
  var i = arr.length;
  while (i--) {
    if (arr[i] === obj) {
      return true;
    }
  }
  return false;
}

/**
 * 删除数组指定元素
 */
function removeByValue(arr, val) {
  for(var i=0; i<arr.length; i++) {
    if(arr[i] == val) {
      arr.splice(i, 1);
      break;
    }
  }
}